package org.jeecg.modules.ywEndFinishedProductEnter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.constant.CommonConstant;
import org.jeecg.constant.InventoryConstant;
import org.jeecg.modules.ywEndFinishedProductEnter.entity.YwEndFinishedProductEnterDetail;
import org.jeecg.modules.ywEndFinishedProductEnter.entity.YwEndFinishedProductEnterMain;
import org.jeecg.modules.ywEndFinishedProductEnter.mapper.YwEndFinishedProductEnterDetailMapper;
import org.jeecg.modules.ywEndFinishedProductEnter.mapper.YwEndFinishedProductEnterMainMapper;
import org.jeecg.modules.ywEndFinishedProductEnter.service.IYwEndFinishedProductEnterDetailService;
import org.jeecg.modules.ywEndFinishedProductEnter.service.IYwEndFinishedProductEnterMainService;
import org.jeecg.modules.ywEndFinishedProductInventory.entity.YwEndFinishedProductInventoryInfo;
import org.jeecg.modules.ywEndFinishedProductInventory.service.IYwEndFinishedProductInventoryInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;

/**
 * @Description: 完成品入库
 * @Author: jeecg-boot
 * @Date: 2024-08-20
 * @Version: V1.0
 */
@Service
public class YwEndFinishedProductEnterMainServiceImpl extends ServiceImpl<YwEndFinishedProductEnterMainMapper, YwEndFinishedProductEnterMain> implements IYwEndFinishedProductEnterMainService {

    @Resource
    private YwEndFinishedProductEnterMainMapper ywEndFinishedProductEnterMainMapper;
    @Resource
    private YwEndFinishedProductEnterDetailMapper ywEndFinishedProductEnterDetailMapper;
    @Resource
    private IYwEndFinishedProductEnterDetailService ywEndFinishedProductEnterDetailService;
    @Resource
    private IYwEndFinishedProductInventoryInfoService ywEndFinishedProductInventoryInfoService;

    @Override
    @Transactional
    public void saveMain(YwEndFinishedProductEnterMain ywEndFinishedProductEnterMain, List<YwEndFinishedProductEnterDetail> ywEndFinishedProductEnterDetailList) {
        // 初始状态：创建完成
        ywEndFinishedProductEnterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.CREATE_END.getCode());
        ywEndFinishedProductEnterMainMapper.insert(ywEndFinishedProductEnterMain);
        if (CollectionUtils.isNotEmpty(ywEndFinishedProductEnterDetailList)) {
            for (YwEndFinishedProductEnterDetail entity : ywEndFinishedProductEnterDetailList) {
                entity.setEnterId(ywEndFinishedProductEnterMain.getId());
                entity.setTotalVolume(entity.getBoxVolume().multiply(new BigDecimal(entity.getTotalNum())));
                entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
                ywEndFinishedProductEnterDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> confirmEnter(String id) {
        YwEndFinishedProductEnterMain enterMain = this.ywEndFinishedProductEnterMainMapper.selectById(id);
        Assert.notNull(enterMain, "入库单数据异常,请联系管理员！");
        Assert.isFalse(InventoryConstant.EnterStatusEnum.DELETE.getCode().equals(enterMain.getEnterStatus()), "入库单状态异常,请联系管理员！");
        List<YwEndFinishedProductEnterDetail> enterDetailList = ywEndFinishedProductEnterDetailService.selectList(id);
        Assert.notEmpty(enterDetailList, "入库单数据异常,请联系管理员！");

        long errorDataCount = enterDetailList.stream().filter(data -> data.getTotalNum() < 0).count();
        Assert.isTrue(errorDataCount == 0, "入库数量不能小于0！");

        // 封装库存信息
        for (YwEndFinishedProductEnterDetail enterDetail : enterDetailList) {
            // 完成品库存：以入库日期、型号编码、仕向编码、货品位置、生产日期为唯一（库存数量、库存体积存储总数）
            List<YwEndFinishedProductInventoryInfo> list = ywEndFinishedProductInventoryInfoService.list(new LambdaQueryWrapper<YwEndFinishedProductInventoryInfo>()
                    .eq(YwEndFinishedProductInventoryInfo::getEnterDate, enterMain.getEnterDate())
                    .eq(YwEndFinishedProductInventoryInfo::getModelCode, enterDetail.getModelCode())
                    .eq(YwEndFinishedProductInventoryInfo::getDirectionCode, enterDetail.getDirectionCode())
                    .eq(YwEndFinishedProductInventoryInfo::getGoodsPosition, enterDetail.getGoodsPosition())
                    .eq(YwEndFinishedProductInventoryInfo::getManufactureDate, enterDetail.getManufactureDate()));
            if (CollectionUtils.isNotEmpty(list)) {
                YwEndFinishedProductInventoryInfo inventoryInfo = list.get(0);
                inventoryInfo.setInventoryNum(inventoryInfo.getInventoryNum() + enterDetail.getTotalNum());
                inventoryInfo.setInventoryVolume(inventoryInfo.getInventoryVolume().add(enterDetail.getTotalVolume()));
                ywEndFinishedProductInventoryInfoService.updateById(inventoryInfo);
            } else {
                YwEndFinishedProductInventoryInfo inventoryInfo = new YwEndFinishedProductInventoryInfo();
                inventoryInfo.setEnterId(enterMain.getId());
                inventoryInfo.setEnterDate(enterMain.getEnterDate());
                inventoryInfo.setModelCode(enterDetail.getModelCode());
                inventoryInfo.setBoxVolume(enterDetail.getBoxVolume());
                inventoryInfo.setDirectionCode(enterDetail.getDirectionCode());
                inventoryInfo.setInventoryNum(enterDetail.getTotalNum());
                inventoryInfo.setInventoryVolume(enterDetail.getTotalVolume());
                inventoryInfo.setGoodsPosition(enterDetail.getGoodsPosition());
                inventoryInfo.setManufactureDate(enterDetail.getManufactureDate());
                inventoryInfo.setStatus(CommonConstant.StatusEnum.YES.getCode());
                ywEndFinishedProductInventoryInfoService.save(inventoryInfo);
            }
        }
        // 更新主表主库状态
        enterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.ENTER_END.getCode());
        this.ywEndFinishedProductEnterMainMapper.updateById(enterMain);

        return Result.OK("入库成功！");
    }

    @Override
    @Transactional
    public void updateMain(YwEndFinishedProductEnterMain ywEndFinishedProductEnterMain, List<YwEndFinishedProductEnterDetail> ywEndFinishedProductEnterDetailList) {
        ywEndFinishedProductEnterMainMapper.updateById(ywEndFinishedProductEnterMain);

        //1.先删除子表数据
        ywEndFinishedProductEnterDetailMapper.deleteByMainId(ywEndFinishedProductEnterMain.getId());

        //2.子表数据重新插入
        if (CollectionUtils.isNotEmpty(ywEndFinishedProductEnterDetailList)) {
            for (YwEndFinishedProductEnterDetail entity : ywEndFinishedProductEnterDetailList) {
                //外键设置
                entity.setId(null);
                entity.setEnterId(ywEndFinishedProductEnterMain.getId());
                // 计算入库体积：单箱体积*入库数量
                entity.setTotalVolume(entity.getBoxVolume().multiply(new BigDecimal(entity.getTotalNum())));
                entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
                entity.setCreateTime(null);
                entity.setCreateBy(null);
                ywEndFinishedProductEnterDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        // 更新子表有效标志
        ywEndFinishedProductEnterDetailMapper.deleteByMainId(id);

        // 更新主表有效标志
        YwEndFinishedProductEnterMain ywEndFinishedProductEnterMain = new YwEndFinishedProductEnterMain();
        ywEndFinishedProductEnterMain.setId(id);
        ywEndFinishedProductEnterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.DELETE.getCode());
        ywEndFinishedProductEnterMainMapper.updateById(ywEndFinishedProductEnterMain);
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            this.delMain(id.toString());
        }
    }

}
